package com.wq.jdk8;

/**
 * @Author: wangqiang20995
 * @Date:2019/7/15
 * @Description:
 * @Resource:
 */
public class LinkedNodeDemo {

    private static class Node {
        private int value;
        private Node next;

        public Node(int value) {
            this.value = value;
        }
    }

    private final Node[] table;

    public LinkedNodeDemo(int size) {
        this.table = new Node[size];
    }

    public void put(int index, Node node) {
        if (table[index] == null) {
            table[index] = node;
        }

        Node n = table[index];
        while (n.next != null) {
            n = n.next;
        }

        n.next = node;
        node.next = null;
    }

    /**
     *
     * @author:wangqiang20995
     * @datetime:2019/7/15 14:52
     * @param: [oriIndex, newIndex]
     * @description:jdk8中对于hashMap的扩容，将Entry的链表从旧的table中移到新的table，并且保持原先的相对顺序
     * @return: void
     *
     **/
    public void moveJdk8(int oriIndex, int newIndex) {

        if (newIndex >= table.length) {
            throw new IllegalArgumentException("newIndex should in [0-" + table.length + "]");
        }

        Node head = null, tail = null;
        Node node = table[oriIndex];
        do {
            if (tail == null) {
                head = node;
            } else {
                tail.next = node;//这一步的目的是为之前的tail接上当前的节点
            }
            tail = node;
        } while ((node = node.next) != null);

        table[newIndex] = head;
        table[oriIndex] = null;
    }

    public void showIndex(int index) {
        if (index >= table.length || table[index] == null) {
            throw new IllegalArgumentException("wrong index");
        }

        Node node = table[index];
        do {
            System.out.printf("%d\t", node.value);
        } while ((node = node.next) != null);
        System.out.println();
    }


    /**
     *
     * @author:wangqiang20995
     * @datetime:2019/7/15 14:49
     * @param: [oriIndex, newIndex]
     * @description:jdk7中对于hashMap的扩容实现方式
     * @return: void
     *
     **/
    public void moveJdk7(int oriIndex, int newIndex) {
        /**
         * 当Entry[index]的链表有多个元素的时候，jdk7是采用逆序的方式，将Entry[i]的链表逆序拼接到新的Entry[p]上面
         */
        if (newIndex >= table.length) {
            throw new IllegalArgumentException("newIndex should in [0-" + table.length + "]");
        }

        Node node = table[oriIndex];
        while (node != null){
            Node next = node.next;//获取原先链表中的下一个节点
            node.next = table[newIndex];//为当前操作的节点设置下一个节点
            table[newIndex] = node;//设置Entry[p]的指针，指向当前操作的接点
            node = next;//
        }
        table[oriIndex] = null;
    }

    public static void main(String args[]) {
        LinkedNodeDemo linkedNodeDemo = new LinkedNodeDemo(4);
        linkedNodeDemo.put(1, new Node(3));
        linkedNodeDemo.put(1, new Node(2));
        linkedNodeDemo.put(1, new Node(5));
        linkedNodeDemo.put(1, new Node(6));
        linkedNodeDemo.put(1, new Node(1));
        linkedNodeDemo.put(1, new Node(7));
        linkedNodeDemo.showIndex(1);

        linkedNodeDemo.moveJdk8(1, 3);
        linkedNodeDemo.showIndex(3);

        linkedNodeDemo.moveJdk7(3,2);
        linkedNodeDemo.showIndex(2);
    }
}
